// --------------------------------------------------------------------------------------------------------------------
// <copyright file="XMLEngineLoader.cs" company="dimamartovoi">
//   Apache License
//   Version 2.0, January 2004
//   http://www.apache.org/licenses
// </copyright>
// <summary>
//   The xml engine loader.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;

using ActorModel.Evolution;

namespace ActorModel.Infrastructure.Configuration.XML
{
    /// <summary>
    ///     The xml engine loader.
    /// </summary>
    public class XMLEngineLoader : IEngineLoader
    {
        #region Public Methods and Operators

        /// <summary>
        /// The load.
        /// </summary>
        /// <param name="evolutionFunc">
        /// The evolution func.
        /// </param>
        /// <returns>
        /// The
        ///     <see>
        ///         <cref>EngineStartParameters</cref>
        ///     </see>
        ///     .
        /// </returns>
        public EngineStartParameters<string> Load(string evolutionFunc)
        {
            var interpreter = new Interpreter();
            Func<string, IEnumerable<string>, IEnumerable<string>> handler = interpreter.Interprete(evolutionFunc);
            return this.Load(handler);
        }

        #endregion

        #region Methods

        /// <summary>
        /// The load.
        /// </summary>
        /// <param name="evolutionFunc">
        /// The evolution func.
        /// </param>
        /// <returns>
        /// The <see cref="EngineStartParameters"/>.
        /// </returns>
        private EngineStartParameters<string> Load(Func<string, IEnumerable<string>, IEnumerable<string>> evolutionFunc)
        {
            CellularAutomationEngineConfigurationSection settings =
                CellularAutomationEngineConfigurationSection.Settings;
            var nodeInitialStates = new Dictionary<int, string>();
            var connectorsInfo = new Dictionary<int, ConnectorInfo<string>>();
            foreach (EngineNodeConfigurationElement node in settings.Nodes)
            {
                foreach (EngineConnectorConfigurationElement connector in node.Connectors)
                {
                    string[] connPair = connector.ConnectedTo.Split(':');
                    int connectedTo = (settings.ConnectorsPerNode * int.Parse(connPair[0])) + int.Parse(connPair[1]);
                    var connectorInfo = new ConnectorInfo<string>(connector.InitState, connectedTo);

                    int connecterId = (settings.ConnectorsPerNode * node.Id) + connector.Id;
                    connectorsInfo.Add(connecterId, connectorInfo);
                }

                nodeInitialStates.Add(node.Id, node.InitState);
            }

            return new EngineStartParameters<string>(
                settings.NodesCount, settings.ConnectorsPerNode, nodeInitialStates, connectorsInfo, evolutionFunc);
        }

        #endregion
    }
}